#include "wresourcemanager.h"

WResourceManager::WResourceManager()
{

}

WResourceManager::~WResourceManager()
{

}

bool WResourceManager::ReadFileToMemoryBuffer(const wxString& filePath, wxMemoryBuffer& buffer)
{
    wxFile file;

    // 以只读方式打开文件
    if (!file.Open(filePath, wxFile::read))
    {
        wxLogError(wxT("无法打开文件: %s"), filePath);
        return false;
    }

    // 获取文件大小
    wxFileOffset fileSize = file.Length();
    if (fileSize == wxInvalidOffset)
    {
        wxLogError(wxT("无法获取文件大小: %s"), filePath);
        file.Close();
        return false;
    }

    // 确保文件大小在合理范围内
    /*if (fileSize > static_cast<wxFileOffset>(SIZE_MAX))
    {
        wxLogError(wxT("文件太大: %s %lld"), filePath,fileSize);
        file.Close();
        return false;
    }*/

    // 准备内存缓冲区
    size_t bufferSize = static_cast<size_t>(fileSize);
    buffer.SetBufSize(bufferSize);

    // 读取文件内容到缓冲区
    ssize_t bytesRead = file.Read(buffer.GetData(), bufferSize);
    file.Close();

    if (bytesRead != static_cast<ssize_t>(bufferSize))
    {
        wxLogError(wxT("读取文件失败: %s (期望读取 %zu 字节，实际读取 %zd 字节)"),
                  filePath, bufferSize, bytesRead);
        return false;
    }

    // 设置实际数据大小
    buffer.SetDataLen(bufferSize);

    return true;
}

/// 得到指定文件的数据大小
wxULongLong WResourceManager::getFileDataSize(wxString filePath)
{
    wxFileName pfilename(filePath);
    if(!pfilename.FileExists())
        return 0;

    return pfilename.GetSize();
}

/// 得到指定文件的数据
wxMemoryBuffer WResourceManager::getFileData(wxString filePath)
{
    wxFileName pfilename(filePath);
    if(!pfilename.FileExists())
        return wxMemoryBuffer();

    wxDateTime creationTime, modificationTime, accessTime;
    if (!pfilename.GetTimes(&creationTime, &modificationTime, &accessTime))
        return wxMemoryBuffer();

    std::map<wxString,ResourceFileInfo>::iterator iter = mResourceFileInfos.find(filePath);
    if(iter == mResourceFileInfos.end() ||
        (*iter).second.modiftime != (modificationTime.IsValid() ? modificationTime : creationTime))
    {
        wxMemoryBuffer buffer;
        if (ReadFileToMemoryBuffer(filePath, buffer))
        {
            mResourceFileInfos[filePath] = ResourceFileInfo(modificationTime.IsValid() ? modificationTime : creationTime,buffer);
        }
    }

    iter = mResourceFileInfos.find(filePath);
    if(iter == mResourceFileInfos.end())
        return wxMemoryBuffer();

    return (*iter).second.buffer;
}
